package ui.panels.commands;

import java.util.ArrayList;

import org.apache.log4j.Logger;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import ui.flowManager.expirimentProperties.AdditionalSettings;
import ui.flowManager.expirimentProperties.AgentRepresentation;
import ui.flowManager.expirimentProperties.ExperimentProperties;
import ui.flowManager.expirimentProperties.ExperimentProperties.Agent_Group;
import auxiliary.AuxiliaryClass;
import gameEngine.agents.choosingStrategy.representation.ManuallAdaptiveRepresentation;
import gameEngine.agents.choosingStrategy.representation.StrategyRepresentation;
import gameEngine.agents.distrebution.representation.DistributionRepresentation;

/**
 * @author vladimir && alon
 *
 *	Save the player properties in ExperimentProperties
 */
public class SavePlayerCommand implements Command{

	ExperimentProperties	props = null;
	
	private int 			gameNumber = 0;
	private int 			playerNumber = 0;

	private String 			epsilonStr = null;
	private String 			competenceStr = null;
	private double 			epsilon = 0;
	private double			competence = 0;
	
	private String 			nextPlayersStr = null;
	private boolean 		morePlayersUpdate = false;
	
	private Agent_Group					group = null;
	private String 						teammateModel = null;
	private String 						analyzer = null;
	private DistributionRepresentation 	distribution = null;
	private StrategyRepresentation 		strategy = null;
	private AdditionalSettings   		additionalSettings = null;
	Logger log = Logger.getLogger(this.getClass());

	
	/**
	 * Save the player properties in ExperimentProperties
	 * Remark - At this point their assumption that the player exist
	 */
	public void execute()
	{
		AgentRepresentation agent = null;
		
		//check that not been forgot to set the parameters
		if(haveForgotToSet())
		{
			log.debug("Player not initialized" );
			return;
		}
		

		//check that the input of epsilon is legal
		if(AuxiliaryClass.isDouble(epsilonStr))
		{
			epsilon = Double.parseDouble(epsilonStr);
		}
		
		//check that the input of competence is legal
		if(AuxiliaryClass.isDouble(competenceStr))
		{
			competence = Double.parseDouble(competenceStr);
		}
		
		//take the agent from ExperimentProperties, to update him
		agent = props.getPlayer(gameNumber, playerNumber, group);
		updateAgent(agent);
		
		//case have more to update
		if(morePlayersUpdate)
		{
			//check the input 
			if((nextPlayersStr != null)&&(AuxiliaryClass.isNumber(nextPlayersStr)))
			{
				int morePlayers = Integer.parseInt(nextPlayersStr);		
				//case exceed number of players in the game (starting counting from current player)
				if(morePlayers > (props.getNumOfPlayers(gameNumber, group)- playerNumber) )
				{
					morePlayers = props.getNumOfPlayers(gameNumber, group) - playerNumber;
				}
				
				//go in loop of number of players to set
				for(int i = 1; i <= morePlayers; ++i)
				{
					//get the agent from ExperimentProperties
					agent = props.getPlayer(gameNumber, playerNumber + i,group);
					//set the agent
					updateAgent(agent);	
				}	
			}
		}
		//end prime loop
		
	}


	
	/**
	 * Set agent data 
	 * @param playerNum
	 */
	public void updateAgent(AgentRepresentation agent)
	{
		//set text fields data
		agent.setEpsilon(epsilon);
		agent.setCompetence(competence);
		
		//set the combos data
		agent.setDistributionType(distribution);
		agent.setAnalyzerType(analyzer);
		agent.setTeammateModelType(teammateModel);
		agent.setStrategyType(strategy);
		agent.setAdditionalSettings(additionalSettings);	
		
		//set initialized
		agent.setInitialized(true);
	}
	
	
	/**
	 * Check if one of parameters was forgot to Set
	 * @return forgot
	 */
	private boolean haveForgotToSet()
	{
		boolean forgot = false ;
		
		if((props == null)||(gameNumber == 0)||(playerNumber == 0))
			forgot = true;
			
		if ((strategy == null) || (teammateModel == null) || (analyzer ==null) || (distribution == null))	
			forgot = true;
		
		if(!strategyInitialized())
		{
			forgot = true;
		}	
		return forgot;	
	}
	
	
	
	private boolean strategyInitialized()
	{
		boolean init = true;
	
		//case it is manual 	
		if(strategy instanceof ManuallAdaptiveRepresentation)
		{
			ManuallAdaptiveRepresentation manual = (ManuallAdaptiveRepresentation)strategy;	
			ArrayList<Integer> strategiesTurns = manual.getStrategiesTurn();
			//sum the strategies turns
			int sumTurns = 0;
			for(int i = 0; i < strategiesTurns.size(); ++i)
			{
				sumTurns+=strategiesTurns.get(i);
			}
			
			if (sumTurns != props.getNumOfTurns(gameNumber))
				init = false;
		}
		
		return init;
	}
	
	
	public void setMorePlayersUpdate(boolean morePlayersUpdate) {
		this.morePlayersUpdate = morePlayersUpdate;
	}

	public void setDistribution(DistributionRepresentation distribution) {
		this.distribution = distribution;
	}

	public void setStrategy(StrategyRepresentation strategy) {
		this.strategy = strategy;
	}

	public void setTeammateModel(String teammateModel) {
		this.teammateModel = teammateModel;
	}

	public void setAnalyzer(String analyzer) {
		this.analyzer = analyzer;
	}

	public void setEpsilonStr(String epsilonStr) {
		this.epsilonStr = epsilonStr;
	}

	public void setCompetenceStr(String competenceStr) {
		this.competenceStr = competenceStr;
	}

	public void setNextPlayersStr(String nextPlayersStr) {
		this.nextPlayersStr = nextPlayersStr;
	}

	public void setGameNumber(int gameNumber) {
		this.gameNumber = gameNumber;
	}

	public void setPlayerNumber(int playerNumber) {
		this.playerNumber = playerNumber;
	}

	public void setProps(ExperimentProperties props) {
		this.props = props;
	}

	public void setAdditionalSettings(AdditionalSettings additionalSettings) {
		this.additionalSettings = additionalSettings;
	}

	public void setGroup(Agent_Group group) {
		this.group = group;
	}
}
